package com.repair.category.facade;


import com.repair.api.category.request.ServiceQeuryByIdRequest;
import com.repair.api.category.request.param.ServiceCategoryDeleteParam;
import com.repair.api.category.request.param.ServiceCategoryGetParam;
import com.repair.api.category.request.param.ServiceCategorySaveParam;
import com.repair.api.category.response.ServiceQueryIdResponse;
import com.repair.api.category.response.ServiceQueryNameResponse;
import com.repair.api.category.response.data.CategoryInfo;
import com.repair.api.category.service.CategoryFacadeService;
import com.repair.category.mapper.ServiceCategoryMapper;
import com.repair.category.pojo.entity.ServiceCategory;
import com.repair.rpc.config.Facade;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@DubboService
public class CategoryFacadeServiceImpl implements CategoryFacadeService {
    @Autowired
    private ServiceCategoryMapper serviceCategoryMapper;

    @Override
    public List<CategoryInfo> getAllCategories(ServiceCategoryGetParam serviceCategoryGetParam) {
        // 查询数据库中的分类信息
        List<CategoryInfo> entities = serviceCategoryMapper.select(serviceCategoryGetParam);

        // 判断参数是否为空或没有设置任何过滤条件
        if (serviceCategoryGetParam == null || isParamEmpty(serviceCategoryGetParam)) {
            // 参数为空或没有设置任何过滤条件，构建完整的树形结构
            return buildTree(entities);
        } else {
            // 参数不为空，构建符合条件的分类及其子分类的树形结构
            return buildFilteredTree(entities, serviceCategoryGetParam);
        }
    }

    @Override
    @Facade
    public ServiceQueryIdResponse getServiceIdById(ServiceQeuryByIdRequest request) {
        CategoryInfo categoryInfo = serviceCategoryMapper.selectById(request.getId());
        ServiceQueryIdResponse response = new ServiceQueryIdResponse();
        response.setServiceId(categoryInfo.getId());
        response.setSuccess(true);
        return response;
    }

    @Override
    @Facade
    public ServiceQueryNameResponse getServiceNameById(ServiceQeuryByIdRequest request) {
        CategoryInfo categoryInfo = serviceCategoryMapper.selectById(request.getId());
        ServiceQueryNameResponse response = new ServiceQueryNameResponse();
        response.setServiceName(categoryInfo.getName());
        response.setSuccess(true);
        return response;
    }

    @Override
    public void save(ServiceCategorySaveParam serviceCategorySaveParam) {
        ServiceCategory serviceCategory = new ServiceCategory();
        BeanUtils.copyProperties(serviceCategorySaveParam,serviceCategory);
        if (serviceCategory.getId()==null){
            serviceCategory.setCreateTime(LocalDateTime.now());
            serviceCategoryMapper.save(serviceCategory);
        }else {
            serviceCategory.setUpdateTime(LocalDateTime.now());
            serviceCategoryMapper.update(serviceCategory);
        }

    }

    @Override
    public void delete(ServiceCategoryDeleteParam serviceCategoryDeleteParam) {
        serviceCategoryMapper.delete(serviceCategoryDeleteParam);
    }
    /**
     * 递归查找所有菜单的子菜单
     */
    private boolean isParamEmpty(ServiceCategoryGetParam param) {
        // 检查参数对象的 id 和 name 是否为空或默认值
        return param == null || (param.getId() == null && (param.getName() == null || param.getName().isEmpty()));
    }

    private List<CategoryInfo> buildTree(List<CategoryInfo> entities) {
        // 过滤出顶级菜单
        List<CategoryInfo> level1Menus = entities.stream()
                .filter(categoryInfo -> categoryInfo.getParentId() == null || categoryInfo.getParentId().longValue() == 0)
                .map(menu -> {
                    menu.setChildren(getChildrens(menu, entities));
                    return menu;
                })
                .sorted(Comparator.comparingInt(menu -> (menu.getSort() == null ? 0 : menu.getSort())))
                .collect(Collectors.toList());

        return level1Menus;
    }

    private List<CategoryInfo> buildFilteredTree(List<CategoryInfo> entities, ServiceCategoryGetParam param) {
        // 找到所有符合条件的分类
        List<CategoryInfo> filteredEntities = entities.stream()
                .filter(categoryInfo -> matchesCondition(categoryInfo, param))
                .collect(Collectors.toList());

        // 构建符合条件的分类及其子分类的树形结构
        return buildTreeFromEntities(filteredEntities, entities);
    }

    private boolean matchesCondition(CategoryInfo category, ServiceCategoryGetParam param) {
        // 检查分类是否符合参数条件
        if (param.getId() != null && !category.getId().equals(param.getId())) {
            return false;
        }
        if (param.getName() != null && !category.getName().toLowerCase().contains(param.getName().toLowerCase())) {
            return false;
        }
        return true;
    }

    private List<CategoryInfo> buildTreeFromEntities(List<CategoryInfo> filteredEntities, List<CategoryInfo> allEntities) {
        // 构建树形结构
        List<CategoryInfo> result = new ArrayList<>();
        for (CategoryInfo entity : filteredEntities) {
            if (!result.contains(entity)) {
                result.add(entity);
            }
            addChildrenRecursively(entity, allEntities, result);
        }
        return result;
    }

    private void addChildrenRecursively(CategoryInfo root, List<CategoryInfo> allEntities, List<CategoryInfo> result) {
        List<CategoryInfo> children = allEntities.stream()
                .filter(categoryInfo -> categoryInfo.getParentId() != null && categoryInfo.getParentId().longValue() == root.getId().longValue())
                .collect(Collectors.toList());

        for (CategoryInfo child : children) {
            if (!result.contains(child)) {
                result.add(child);
            }
            addChildrenRecursively(child, allEntities, result);
        }
    }

    private List<CategoryInfo> getChildrens(CategoryInfo root, List<CategoryInfo> all) {
        List<CategoryInfo> children = all.stream()
                .filter(categoryInfo -> categoryInfo.getParentId() != null && categoryInfo.getParentId().longValue() == root.getId().longValue())
                .map(categoryEntity -> {
                    // 递归找到子菜单
                    categoryEntity.setChildren(getChildrens(categoryEntity, all));
                    return categoryEntity;
                })
                .sorted(Comparator.comparingInt(menu -> (menu.getSort() == null ? 0 : menu.getSort())))
                .collect(Collectors.toList());

        return children;
    }

}
